package db

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/google/uuid"
	"gomonitor-server/src/domain"
	"gomonitor-server/src/dto"
	"gomonitor-server/src/mylog"
	"reflect"
	"time"
)

func RecordDb(sysInfo dto.SysInfo) {
	dbTool, err := GetConnection()
	if err != nil {
		// 处理错误
		mylog.Logger.Error("连接MySQL失败", err)
		return
	}

	cpuCores := len(sysInfo.CpuInfo)
	var sumCpuRate float64
	for _, info := range sysInfo.CpuInfo {
		sumCpuRate += info.UsedRate
	}
	hostId := uuid.New().String()
	cpuRate := sumCpuRate / float64(cpuCores)

	// net
	netCount := len(sysInfo.NetInfo)
	net1Name := ""
	net1Ip := ""
	net1Mac := ""

	net2Name := ""
	net2Ip := ""
	net2Mac := ""

	if netCount == 1 {
		net1Name = sysInfo.NetInfo[0].Name
		net1Ip = sysInfo.NetInfo[0].Ip
		net1Mac = sysInfo.NetInfo[0].Mac
	} else if netCount >= 2 {
		net1Name = sysInfo.NetInfo[0].Name
		net1Ip = sysInfo.NetInfo[0].Ip
		net1Mac = sysInfo.NetInfo[0].Mac

		net2Name = sysInfo.NetInfo[1].Name
		net2Ip = sysInfo.NetInfo[1].Ip
		net2Mac = sysInfo.NetInfo[1].Mac
	}

	//disk
	disk1Device := ""
	disk1MountPoint := ""
	disk1Path := ""
	disk1Size := 0.0
	disk1Used := 0.0
	disk1Free := 0.0
	disk1UsedRate := 0.0

	disk2Device := ""
	disk2MountPoint := ""
	disk2Path := ""
	disk2Size := 0.0
	disk2Used := 0.0
	disk2Free := 0.0
	disk2UsedRate := 0.0

	disk3Device := ""
	disk3MountPoint := ""
	disk3Path := ""
	disk3Size := 0.0
	disk3Used := 0.0
	disk3Free := 0.0
	disk3UsedRate := 0.0

	disk4Device := ""
	disk4MountPoint := ""
	disk4Path := ""
	disk4Size := 0.0
	disk4Used := 0.0
	disk4Free := 0.0
	disk4UsedRate := 0.0

	diskCount := len(sysInfo.DiskInfo)
	if diskCount == 1 {
		disk1 := sysInfo.DiskInfo[0]
		disk1Device = disk1.Device
		disk1MountPoint = disk1.MountPoint
		disk1Path = disk1.Path
		disk1Size = disk1.Size
		disk1Used = disk1.Used
		disk1Free = disk1.Free
		disk1UsedRate = disk1.UsedRate
	} else if diskCount == 2 {
		disk1 := sysInfo.DiskInfo[0]
		disk1Device = disk1.Device
		disk1MountPoint = disk1.MountPoint
		disk1Path = disk1.Path
		disk1Size = disk1.Size
		disk1Used = disk1.Used
		disk1Free = disk1.Free
		disk1UsedRate = disk1.UsedRate

		disk2 := sysInfo.DiskInfo[1]
		disk2Device = disk2.Device
		disk2MountPoint = disk2.MountPoint
		disk2Path = disk2.Path
		disk2Size = disk2.Size
		disk2Used = disk2.Used
		disk2Free = disk2.Free
		disk2UsedRate = disk2.UsedRate

	} else if diskCount == 3 {
		disk1 := sysInfo.DiskInfo[0]
		disk1Device = disk1.Device
		disk1MountPoint = disk1.MountPoint
		disk1Path = disk1.Path
		disk1Size = disk1.Size
		disk1Used = disk1.Used
		disk1Free = disk1.Free
		disk1UsedRate = disk1.UsedRate

		disk2 := sysInfo.DiskInfo[1]
		disk2Device = disk2.Device
		disk2MountPoint = disk2.MountPoint
		disk2Path = disk2.Path
		disk2Size = disk2.Size
		disk2Used = disk2.Used
		disk2Free = disk2.Free
		disk2UsedRate = disk2.UsedRate

		disk3 := sysInfo.DiskInfo[2]
		disk3Device = disk3.Device
		disk3MountPoint = disk3.MountPoint
		disk3Path = disk3.Path
		disk3Size = disk3.Size
		disk3Used = disk3.Used
		disk3Free = disk3.Free
		disk3UsedRate = disk3.UsedRate

	} else if diskCount >= 4 {
		disk1 := sysInfo.DiskInfo[0]
		disk1Device = disk1.Device
		disk1MountPoint = disk1.MountPoint
		disk1Path = disk1.Path
		disk1Size = disk1.Size
		disk1Used = disk1.Used
		disk1Free = disk1.Free
		disk1UsedRate = disk1.UsedRate

		disk2 := sysInfo.DiskInfo[1]
		disk2Device = disk2.Device
		disk2MountPoint = disk2.MountPoint
		disk2Path = disk2.Path
		disk2Size = disk2.Size
		disk2Used = disk2.Used
		disk2Free = disk2.Free
		disk2UsedRate = disk2.UsedRate

		disk3 := sysInfo.DiskInfo[2]
		disk3Device = disk3.Device
		disk3MountPoint = disk3.MountPoint
		disk3Path = disk3.Path
		disk3Size = disk3.Size
		disk3Used = disk3.Used
		disk3Free = disk3.Free
		disk3UsedRate = disk3.UsedRate

		disk4 := sysInfo.DiskInfo[3]
		disk4Device = disk4.Device
		disk4MountPoint = disk4.MountPoint
		disk4Path = disk4.Path
		disk4Size = disk4.Size
		disk4Used = disk4.Used
		disk4Free = disk4.Free
		disk4UsedRate = disk4.UsedRate
	}
	mylog.Logger.Debugf("开始插入主机%s日志", net1Ip)

	host := domain.Host{ID: hostId, OS: sysInfo.Os, KernelVersion: sysInfo.KernelVersion, HardArch: sysInfo.HardArch,
		MemTotal: sysInfo.MemInfo.Total, MemUsed: sysInfo.MemInfo.Used, MemFree: sysInfo.MemInfo.Free, MemUsedRate: sysInfo.MemInfo.UsedRate,
		CPUCores: len(sysInfo.CpuInfo), CPUUsedRate: cpuRate, Hostname: sysInfo.Hostname, CreatedTime: time.Now(),
		Net1Name: net1Name, Net1IP: net1Ip, Net1Mac: net1Mac, Net2Name: net2Name, Net2IP: net2Ip, Net2Mac: net2Mac,
		Disk1Device: disk1Device, Disk1MountPoint: disk1MountPoint, Disk1Path: disk1Path, Disk1Size: disk1Size, Disk1Used: disk1Used, Disk1Free: disk1Free, Disk1UsedRate: disk1UsedRate,
		Disk2Device: disk2Device, Disk2MountPoint: disk2MountPoint, Disk2Path: disk2Path, Disk2Size: disk2Size, Disk2Used: disk2Used, Disk2Free: disk2Free, Disk2UsedRate: disk2UsedRate,
		Disk3Device: disk3Device, Disk3MountPoint: disk3MountPoint, Disk3Path: disk3Path, Disk3Size: disk3Size, Disk3Used: disk3Used, Disk3Free: disk3Free, Disk3UsedRate: disk3UsedRate,
		Disk4Device: disk4Device, Disk4MountPoint: disk4MountPoint, Disk4Path: disk4Path, Disk4Size: disk4Size, Disk4Used: disk4Used, Disk4Free: disk4Free, Disk4UsedRate: disk4UsedRate}
	//dbTool.db.Model(&domain.Host{}).Create(host)
	dbTool.db.Create(host)
	updateLastInfo(&host, dbTool)
	mylog.Logger.Debugf("结束插入主机%s日志", net1Ip)
	if err != nil {
		mylog.Logger.Errorf("插入主机%s日志错误:%s", net1Ip, err.Error())
		return
	}

}

func objCopy(src interface{}, dest interface{}) {
	srcValue := reflect.ValueOf(src).Elem()
	destValue := reflect.ValueOf(dest).Elem()

	for i := 0; i < srcValue.NumField(); i++ {
		srcField := srcValue.Type().Field(i)
		srcFieldValue := srcValue.Field(i)

		destField := destValue.FieldByName(srcField.Name)

		if destField.IsValid() && destField.CanSet() {
			destField.Set(srcFieldValue)
		}
	}
}

func updateLastInfo(host *domain.Host, dbTool *DbTool) {
	var hostLasts []domain.HostLast
	dbTool.db.Model(&domain.HostLast{}).Where("hostname=? and net1_ip=?", host.Hostname, host.Net1IP).Find(&hostLasts)
	if len(hostLasts) > 0 {
		hostLast := hostLasts[0]
		objCopy(host, &hostLast)
		hostLast.UpdatedTime = time.Now()
		dbTool.db.Model(&domain.HostLast{}).Where("hostname=? and net1_ip=?", host.Hostname, host.Net1IP).Save(hostLast)
	} else {
		var hostLast domain.HostLast
		objCopy(host, &hostLast)
		hostLast.UpdatedTime = time.Now()
		dbTool.db.Model(&domain.HostLast{}).Create(hostLast)
	}

}
